package com.wlb365.financing.config;

import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
import com.baomidou.mybatisplus.core.parser.ISqlParser;
import com.baomidou.mybatisplus.core.parser.ISqlParserFilter;
import com.baomidou.mybatisplus.core.parser.SqlParserHelper;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.extension.plugins.tenant.TenantHandler;
import com.baomidou.mybatisplus.extension.plugins.tenant.TenantSqlParser;
import com.wlb365.financing.common.constants.SysConstant;
import com.wlb365.financing.common.utils.ShiroUtil;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.LongValue;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.reflection.MetaObject;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import javax.sql.DataSource;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 概述：mybatisplus配置
 * </p>
 *
 * @author zwh
 * @version 1.0
 * @copyRight 北京微利宝信息技术有限公司  All right reserved.
 * @date 2020/3/21
 */
@Configuration
@MapperScan("com.wlb365.financing.modules.*.mapper")
@EnableTransactionManagement
public class MybatisPlusConfig {
    /**
     * 要进行部门id权限控制的表名，以逗号结尾isv_keys,sys_user,
     */
    private String TABLE_NAMES = "";

    /**
     * druid注入
     *
     * @return dataSource
     */
    @Bean(name = "dataSource")
    @ConfigurationProperties(prefix = "spring.datasource.druid")
    public DataSource dataSource() {
        return DruidDataSourceBuilder.create().build();
    }

    /**
     * 配置事物管理器
     *
     * @return DataSourceTransactionManager
     */
    @Bean(name = "transactionManager")
    public DataSourceTransactionManager transactionManager() {
        return new DataSourceTransactionManager(dataSource());
    }

    /**
     * 配置分页插件
     *
     * @return page
     */
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        PaginationInterceptor page = new PaginationInterceptor();
        page.setDialectType("mysql");

        //多租户，参考：https://mybatis.plus/guide/tenant.html
        List<ISqlParser> sqlParserList = new ArrayList<>();
        TenantSqlParser tenantSqlParser = new TenantSqlParser();
        tenantSqlParser.setTenantHandler(new TenantHandler() {
            @Override
            public Expression getTenantId(boolean where) {
                // 该 where 条件 3.2.0 版本开始添加的，用于分区是否为在 where 条件中使用
                return new LongValue(ShiroUtil.getUser().getDeptId());
            }

            @Override
            public String getTenantIdColumn() {
                return "dept_id";
            }

            @Override
            public boolean doTableFilter(String tableName) {
                //已经登录，并且为管理员，不进行权限过滤
                if (ShiroUtil.isLogin() && SysConstant.ADMIN.equals(ShiroUtil.getUser().getUsername())) {
                    return true;
                }
                if(ShiroUtil.isLogin()){
                    // 需要进行权限控制的表名
                    if (TABLE_NAMES.indexOf(tableName + ",") > -1) {
                        //false进行权限控制
                        return false;
                    }
                }
                //true不进行权限控制
                return true;
            }
        });

        sqlParserList.add(tenantSqlParser);
        page.setSqlParserList(sqlParserList);
        page.setSqlParserFilter(new ISqlParserFilter() {
            @Override
            public boolean doFilter(MetaObject metaObject) {
                MappedStatement ms = SqlParserHelper.getMappedStatement(metaObject);
                // 过滤自定义查询此时无租户信息约束【 麻花藤 】出现
                if ("com.baomidou.springboot.mapper.UserMapper.selectListBySQL".equals(ms.getId())) {
                    return true;
                }
                return false;
            }
        });

        return page;
    }

}
